{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Routed Sequencing"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This model introduces routing in the sequencing model. The addition of routing allows the system to choose between two different actions: whether to go through the sequence, or be driven by the visual input as explained in the book. For instance, if the visual input has its value set to 0.8*START+D, the model will begin cycling through at D->E, etc. Thus in this model, the input doesn't prevent the activation of the second rule in the sequence. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# Setup the environment\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "\n",
    "import nengo\n",
    "from nengo import spa  # import spa related packages"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Create the Model\n",
    "The parameters used in the model are as described in the book, with 16 dimensions for all semantic pointers.\n",
    "\n",
    "In Nengo 1.4, a buffer element for representing the `vision` was created by using Buffer() as described in the book. However, in Nengo 2.0, you will have to use State() with feedback parameter set to 0 (which is the default value in nengo)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# Number of dimensions for the Semantic Pointers\n",
    "dimensions = 16\n",
    "\n",
    "# Make a model object with the SPA network\n",
    "model = spa.SPA(label='Routed_Sequence', seed=20)\n",
    "\n",
    "with model:\n",
    "    # Specify the modules to be used\n",
    "    model.state = spa.State(dimensions=dimensions, feedback=1, feedback_synapse=0.01)\n",
    "    model.vision = spa.State(dimensions=dimensions) \n",
    "    \n",
    "    # Specify the action mapping\n",
    "    actions = spa.Actions(\n",
    "        'dot(vision, START) --> state = vision',\n",
    "        'dot(state, A) --> state = B',\n",
    "        'dot(state, B) --> state = C',\n",
    "        'dot(state, C) --> state = D',\n",
    "        'dot(state, D) --> state = E',\n",
    "        'dot(state, E) --> state = A'\n",
    "    )\n",
    "    \n",
    "    # Creating the BG and Thalamus components that confirm to the specified rules\n",
    "    model.BG = spa.BasalGanglia(actions=actions)\n",
    "    model.thal = spa.Thalamus(model.BG)\n",
    "    \n",
    "    # Function that provides the model with an initial input semantic pointer.\n",
    "    def start(t):\n",
    "        if t < 0.4:\n",
    "            return '0.8*START+D'\n",
    "        else:\n",
    "            return '0'\n",
    "\n",
    "    # Input\n",
    "    model.input = spa.Input(vision=start)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Run the Model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# Import the nengo_gui visualizer\n",
    "from nengo_gui.ipython import IPythonViz\n",
    "IPythonViz(model, \"ch7-spa-sequence-routed.py.cfg\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Press the play button in the visualizer to run the simulation. You should see the graphs as shown in the figure below.\n",
    "\n",
    "The graph on the bottom-left shows the visual input recieved by the model, the state graph in the middle shows the semantic pointer representation of the values stored in the `state` ensemble. The actions graph on bottom-right shows the current transition or the action being executed, and the state graph on top-right shows the utility (similarity) of the current basal ganglia input (i.e., state) with the possible vocabulary vectors. \n",
    "\n",
    "You can see that in this case, even though the input is applied for 400ms, it doesn't prevent the activation of the second and subsequent rules in the sequence."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "from IPython.display import Image\n",
    "Image(filename='ch7-spa-sequence-routed.png')"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.10"
  },
  "widgets": {
   "state": {},
   "version": "1.1.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
